package controllers;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.io.File;
import java.io.IOException;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.xml.parsers.ParserConfigurationException;

import models.FeaturesModel;
import models.LexiconFeaturesModel;
import models.OntologyModel;

import objects.Concept;
import objects.Constituent;

import org.xml.sax.SAXException;

import views.MainPanel;

import controllers.listeners.*;
import controllers.listeners.semrep.*;

/* Starts program; Initializes Main UI and listeners; Initializes data */
public class MainModuleController {
	
	public static File file;
	
	public static void main(String args[]) {
		try { 
			new MainModuleController();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public MainModuleController() throws ParserConfigurationException, SAXException, IOException {
		/* Initialize UI */
		JFrame frame = new JFrame();
		frame.setMinimumSize(new Dimension(550, 400));
		frame.setSize(900, 600);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("LINGUIST ASSISTANT'S ASSISTANT");
		MainPanel mp = new MainPanel();
		frame.getContentPane().add(mp);
		
		/** Initialize listeners **/
		
		MenuNewSemRepActionListener newSemRepListener = new MenuNewSemRepActionListener();
		OpenSemRepActionListener openListener = new OpenSemRepActionListener();
		SaveSemRepActionListener saveListener = new SaveSemRepActionListener();
		SaveAsSemRepActionListener saveAsListener = new SaveAsSemRepActionListener();
		MenuExitActionListener exitListener = new MenuExitActionListener();
		MenuFeaturesActionListener menuFeaturesListener = new MenuFeaturesActionListener();
		MenuLexiconActionListener lexiconListener = new MenuLexiconActionListener();
		MenuOntologyActionListener ontologyListener = new MenuOntologyActionListener();
		MenuNewLanguageActionListener newSemLangListener = new MenuNewLanguageActionListener();
		TranslateListener genListener = new TranslateListener();
		AddFeatureActionListener addFeatureListener = new AddFeatureActionListener();
		TableMouseListener tableListener = new TableMouseListener();
		DeleteFeatureActionListener deleteFeatureListener = new DeleteFeatureActionListener();
		EditConstituentActionListener editConListener = new EditConstituentActionListener();
		DeleteConstituentActionListener deleteConListener = new DeleteConstituentActionListener();
		
		newSemRepListener.setView(mp);
		openListener.setView(mp);
		saveListener.setView(mp);
		saveAsListener.setView(mp);
		ontologyListener.setMainPanel(mp);
		genListener.setView(mp);
		addFeatureListener.setView(mp);
		tableListener.setView(mp);
		deleteFeatureListener.setView(mp);
		editConListener.setView(mp);
		deleteConListener.setView(mp);
		
		mp.addMenuNewSemRepListener(newSemRepListener);
		mp.addOpenListener(openListener);
		mp.addSaveListener(saveListener);
		mp.addSaveAsListener(saveAsListener);
		mp.addExitListener(exitListener);
		mp.addMenuFeaturesListener(menuFeaturesListener);
		mp.addMenuLexiconListener(lexiconListener);
		mp.addMenuOntologyListener(ontologyListener);
		mp.addMenuNewSemLangListener(newSemLangListener);
		mp.addTranslateListener(genListener);
		mp.addAddFeatureListener(addFeatureListener);
		mp.addTableListener(tableListener);
		mp.addDeleteFeatureListener(deleteFeatureListener);
		mp.addEditConstituentListener(editConListener);
		mp.addDeleteConstituentListener(deleteConListener);
		
		/* Show UI */
		frame.revalidate();
		frame.setVisible(true);
		
		/* Initialize data */
		FeaturesModel.read();
		LexiconFeaturesModel.read();
		OntologyModel.read();
	}
	
	/* Occurs when a constituent is double-clicked. */
	/* Inserts a new constituent into the semantic representation */
	public static void insertSemantic(Constituent con, MainPanel view) throws ParserConfigurationException, SAXException, IOException {
		JTextField txtConcept = new JTextField();
		JTextField txtSense = new JTextField();
		JComboBox<String> cmbConstituent = new JComboBox<>();
		JComboBox<String> cmbPosition = new JComboBox<>();
    	cmbPosition.addItem("Left");
    	cmbPosition.addItem("Right");
    	cmbPosition.addItem("Inside");
    	
    	for (Constituent currentConstituent : FeaturesModel.getFeatures()) {
			cmbConstituent.addItem(currentConstituent.getLabel());
		}
		
		Object[] message = {
		        "Select insert postion:", cmbPosition,  
		        "Select constituent type:", cmbConstituent,  
		        "Enter concept value:", txtConcept,  
		        "Enter sense value:", txtSense,  
		    };
    	
		int option = JOptionPane.showConfirmDialog(new JFrame(), message, "Add Semantic", JOptionPane.OK_CANCEL_OPTION);
		
		if (option == JOptionPane.OK_OPTION) {
	        
        	Constituent newCon = new Constituent();
        	newCon.setLabel(cmbConstituent.getSelectedItem().toString());
        	newCon.setConcept(new Concept(txtConcept.getText()));
        	newCon.setSense(txtSense.getText());
        	
        	Constituent currCon = view.getCurrCon();
        	Constituent parent = currCon.getParent();
        	
        	if (parent == null) {
        		if (cmbPosition.getSelectedItem().toString().equals("Inside")) {
    	        	newCon.setParent(currCon);
    	        	currCon.getConstituentList().add(newCon);
    	        }
        		else {
        			JOptionPane.showMessageDialog(null, "Constituents can only be inserted inside the main constituent.", "Error", JOptionPane.ERROR_MESSAGE);
        		}
        	}
        	
        	else {
        		int i = 0;
            	
        		for (i = 0; i < parent.getConstituentList().size(); i++)
            		if (parent.getConstituentList().get(i).equals(currCon))
            			break;
            	
    	        if (cmbPosition.getSelectedItem().toString().equals("Left")) {
    	        	newCon.setParent(parent);
    	        	currCon.getParent().getConstituentList().add(i, newCon);
    	        }

    	        else if (cmbPosition.getSelectedItem().toString().equals("Right")) {
    	        	newCon.setParent(parent);
    	        	currCon.getParent().getConstituentList().add(i + 1, newCon);
    	        }

    	        else if (cmbPosition.getSelectedItem().toString().equals("Inside")) {
    	        	newCon.setParent(currCon);
    	        	currCon.getConstituentList().add(newCon);
    	        }
        	}
	        
        	view.clearPanels();
	        view.loadSemantic(setTextAreaSemantic(view.getConstituent(), view));
	    }
	}
	
	/* Occurs when a new sem rep is created, a sem rep is opened, */
	/* and when a constituent of an open sem rep is edited or deleted. */
	/* Creates the recursive panels like [CL[NP[N]]] as well as its counterpart */
	public static JPanel setTextAreaSemantic(Constituent con, MainPanel view) {
		JPanel panel = new JPanel();
		panel.setLayout(new FlowLayout(FlowLayout.CENTER, 3,0));
		panel.setOpaque(false);
		
		if (con.getConcept().getName() != null && con.getSense() == null) {
			JLabel label = new JLabel(con.getConcept().getName());
			panel.add(label);
		}
		else if (con.getConcept().getName() != null) {
			if (con.getSense() != null  && !con.getSense().equals("")) {
				JLabel label = new JLabel(con.getConcept().getName() + "-" + con.getSense());
				panel.add(label);
			}
			else {
				JLabel label = new JLabel(con.getConcept().getName());
				panel.add(label);
			}
		}
		
		JLabel openBracket = new JLabel("[");
		view.addToButtonsPanel(openBracket);
		
		JLabel button = new JLabel(con.getLabel());
		
		HighlightConstituentMouseListener listener = new HighlightConstituentMouseListener();
		listener.setView(view);
		listener.setPanel(panel);
		listener.setLabel(button);
		listener.setCurrentConstituent(con);
		
		button.addMouseListener(listener);
		panel.addMouseListener(listener);
		
		view.addToButtonsPanel(button);
		
		for (int i = 0;i < con.getConstituentList().size();i++) {
			panel.add(setTextAreaSemantic(con.getConstituentList().get(i), view));
		}
		
		JLabel closeBracket = new JLabel("]");
		view.addToButtonsPanel(closeBracket);
		
		return panel;
	}
	
}
